<!DOCTYPE html>
<html lang="zh-CN">
    <head>
  <!-- 元数据 -->
  <meta charset="utf-8">
  <link rel="icon" href="/blog/images/logo.png">
  
  <title>【Pytest】基本使用 | 溪岚花的博客</title>
  
  <meta name="author" content="林家隆" />
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="robots" content="index,follow" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <meta name="format-detection" content="telphone=no, email=no" />
  
    <meta name="keywords" content="Pytest, Python" />
  
  <meta name="description" content="pytest 简介 pytest 是一个非常成熟的 python 的单元框架，比 unittest 更灵活。  pytest 可以和 selenium，requests，appium 结合实现 web 自动化，接口自动化，app 自 动化。  pytest 可以实现测试函数的跳过以及重新执行失败的测试函数。  pytest 可以和 allure 生成非常美观的测试报告。  pytest 可以和 J">
<meta property="og:type" content="article">
<meta property="og:title" content="【Pytest】基本使用">
<meta property="og:url" content="https://lin316.gitee.io/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/index.html">
<meta property="og:site_name" content="溪岚花的博客">
<meta property="og:description" content="pytest 简介 pytest 是一个非常成熟的 python 的单元框架，比 unittest 更灵活。  pytest 可以和 selenium，requests，appium 结合实现 web 自动化，接口自动化，app 自 动化。  pytest 可以实现测试函数的跳过以及重新执行失败的测试函数。  pytest 可以和 allure 生成非常美观的测试报告。  pytest 可以和 J">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://lin316.gitee.io/blog/blog/images/logo.png">
<meta property="article:published_time" content="2024-02-26T06:00:00.000Z">
<meta property="article:modified_time" content="2025-11-20T11:35:22.287Z">
<meta property="article:author" content="林家隆">
<meta property="article:tag" content="Python">
<meta property="article:tag" content="Pytest">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://lin316.gitee.io/blog/blog/images/logo.png">
  
  <!-- 站点验证相关 -->
  
    
    
    
  
  <!-- 样式表文件 -->
  <link rel="stylesheet" id="kratos-css" href="/blog/css/kratosr.min.css" media="all"></script>
  
    <link rel="stylesheet" id="darkmode-css" href="/blog/css/kr-color-dark.min.css" media="(prefers-color-scheme: dark)"></script>
    <script src="/blog/js/kr-dark.min.js"></script>
  
  
    <link rel="stylesheet" id="highlight-css" href="/blog/css/highlight/night-eighties.min.css" media="all"></script>
  
  <link rel="stylesheet" id="fontawe-css" href="/blog/vendors/font-awesome@4.7.0/css/font-awesome.min.css" media="all"></script>
  <link rel="stylesheet" id="nprogress-css" href="/blog/vendors/nprogress@0.2.0/nprogress.css" media="all"></script>
  
  
  
    <link rel="stylesheet" href="/blog/vendors/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css"></script>
  
  <!-- 不得不预先加载的一些JS文件 -->
  <script src="/blog/vendors/jquery@3.6.0/dist/jquery.min.js"></script>
  
  
  <style>
    
    
  </style>
  
<meta name="generator" content="Hexo 6.3.0"></head>


    <body class="custom-background">
        <div id="kratos-wrapper">
    <div id="kratos-page">
        <div id="kratos-header">
            <header id="kratos-desktop-topnav" class="kratos-topnav">
                <div class="container">
                    <div class="nav-header">
                        <nav id="kratos-menu-wrap">
                            <ul id="kratos-primary-menu" class="sf-menu">
                                
                                    
                                        <li>
                                            
                                                <a href="/blog/">
                                            
                                                
                                                    <i class="fa fa-home"></i>
                                                
                                                首页
                                            </a>
                                            
                                        </li>
                                    
                                        <li>
                                            
                                                <a href="/blog/archives/">
                                            
                                                
                                                    <i class="fa fa-file"></i>
                                                
                                                归档
                                            </a>
                                            
                                        </li>
                                    
                                        <li>
                                            
                                                <a href="/blog/tags/">
                                            
                                                
                                                    <i class="fa fa-tag"></i>
                                                
                                                标签
                                            </a>
                                            
                                        </li>
                                    
                                        <li>
                                            
                                                <a href="/blog/categories/">
                                            
                                                
                                                    <i class="fa fa-folder"></i>
                                                
                                                目录
                                            </a>
                                            
                                        </li>
                                    
                                        <li>
                                            
                                                <a href="/blog/search/">
                                            
                                                
                                                    <i class="fa fa-search"></i>
                                                
                                                搜索
                                            </a>
                                            
                                        </li>
                                    
                                
                            </ul>
                        </nav>
                    </div>
                </div>
            </header>
            <header id="kratos-mobile-topnav" class="kratos-topnav">
                <div class="container">
                    <div class="color-logo"><a href="/blog/">溪岚花的博客</a></div>
                    <div class="nav-toggle">
                        <a class="kratos-nav-toggle js-kratos-nav-toggle">
                            <i></i>
                        </a>
                    </div>
                </div>
            </header>
        </div>
        <div class="kratos-start kratos-hero-2">
            <!-- <div class="kratos-overlay"></div> -->
            <div class="kratos-cover kratos-cover-2 text-center">
                <div class="desc desc2 animate-box">
                    <a href="/blog/">
                        <h2 style="opacity: 0.2;">溪岚花的博客</h2> <br />
                        <span></span>
                    </a>
                </div>
            </div>
        </div>

        <div id="kratos-blog-post">
            <div class="container">
                <div id="main" class="row">
                    

        

            <section class="col-md-8">

        

            <article itemscope itemtype="https://schema.org/Article">
    
    <link itemprop="mainEntityOfPage" href="https://lin316.gitee.io/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/">
    <div class="kratos-hentry kratos-post-inner clearfix">
        <header class="kratos-entry-header">
            
                <h1 class="kratos-entry-title text-center" itemprop="name headline">【Pytest】基本使用</h1>
            
            
            <ul class="kratos-post-meta text-center">
                <li><time datetime="2024-02-26T06:00:00.000Z" itemprop="datePublished"><i class="fa fa-calendar"></i> 2024-02-26</time></li>
                <li itemprop="author" itemscope itemtype="https://schema.org/Person">
                    <i class="fa fa-user"></i> 作者 <span itemprop="name">林家隆</span>
                </li>
                
                    <li>
                        <i class="fa fa-edit"></i> 
                        
                        
                            8.17K
                        
                        字
                    </li>
                
                
            </ul>
        </header>
        <div class="kratos-post-content">
            
            <div id="expire-alert" class="alert alert-warning hidden" role="alert">
                <div class="icon"><i class="fa fa-warning"></i></div>
                <div class="text"><p>本文最后编辑于 <time datetime="1763638522287"></time> 前，其中的内容可能需要更新。</p></div>
            </div>
            
            
            
                <div class="kratos-post-inner-toc toc-div-class" >
                    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-%E7%AE%80%E4%BB%8B"><span class="toc-number">1.</span> <span class="toc-text">pytest 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%96%E5%86%99%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%E7%9A%84%E9%BB%98%E8%AE%A4%E8%A7%84%E5%88%99"><span class="toc-number">2.</span> <span class="toc-text">编写测试函数的默认规则</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BC%96%E5%86%99%E8%A7%84%E5%88%99"><span class="toc-number">2.1.</span> <span class="toc-text">编写规则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BD%A2%E5%BC%8F%E7%BC%96%E5%86%99%E7%94%A8%E4%BE%8B"><span class="toc-number">2.2.</span> <span class="toc-text">函数形式编写用例</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E5%BD%A2%E5%BC%8F%E7%BC%96%E5%86%99%E7%94%A8%E4%BE%8B"><span class="toc-number">2.3.</span> <span class="toc-text">类形式编写用例</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E8%A1%8C-pytest-%E6%96%B9%E5%BC%8F"><span class="toc-number">3.</span> <span class="toc-text">运行 pytest 方式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%A8%A1%E5%BC%8F"><span class="toc-number">3.1.</span> <span class="toc-text">命令行模式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#pytest-%E5%91%BD%E4%BB%A4%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">3.1.1.</span> <span class="toc-text">pytest 命令的使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0"><span class="toc-number">3.1.2.</span> <span class="toc-text">自定义命令行参数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E5%87%BD%E6%95%B0%E6%A8%A1%E5%BC%8F"><span class="toc-number">3.2.</span> <span class="toc-text">主函数模式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-ini-%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">4.</span> <span class="toc-text">pytest.ini 全局配置文件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-ini-%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9"><span class="toc-number">4.1.</span> <span class="toc-text">pytest.ini 文件内容</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-fixture-%E5%AE%9E%E7%8E%B0%E9%83%A8%E5%88%86%E5%89%8D%E5%90%8E%E7%BD%AE%E6%93%8D%E4%BD%9C"><span class="toc-number">5.</span> <span class="toc-text">使用 fixture 实现部分前后置操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-fixture-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.</span> <span class="toc-text">@pytest.fixture() 参数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#scope-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.1.</span> <span class="toc-text">scope 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#autouse-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.2.</span> <span class="toc-text">autouse 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#params-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.3.</span> <span class="toc-text">params 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ids-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.4.</span> <span class="toc-text">ids 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#name-%E5%8F%82%E6%95%B0"><span class="toc-number">5.1.5.</span> <span class="toc-text">name 参数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#conftest-py-%E6%96%87%E4%BB%B6"><span class="toc-number">5.2.</span> <span class="toc-text">conftest.py 文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%90%84%E7%A7%8D%E5%89%8D%E5%90%8E%E5%9B%BA%E4%BB%B6%E7%9A%84%E4%BC%98%E5%85%88%E7%BA%A7"><span class="toc-number">5.3.</span> <span class="toc-text">各种前后固件的优先级</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-mark-%E6%A0%87%E8%AE%B0%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">6.</span> <span class="toc-text">pytest.mark 标记的使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-parametrize"><span class="toc-number">6.1.</span> <span class="toc-text">pytest.mark.parametrize</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8"><span class="toc-number">6.1.1.</span> <span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0"><span class="toc-number">6.1.2.</span> <span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B"><span class="toc-number">6.1.3.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-skip"><span class="toc-number">6.2.</span> <span class="toc-text">pytest.mark.skip</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-1"><span class="toc-number">6.2.1.</span> <span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0-1"><span class="toc-number">6.2.2.</span> <span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-1"><span class="toc-number">6.2.3.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-skipif"><span class="toc-number">6.3.</span> <span class="toc-text">pytest.mark.skipif</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-2"><span class="toc-number">6.3.1.</span> <span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0-2"><span class="toc-number">6.3.2.</span> <span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-2"><span class="toc-number">6.3.3.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-usefixtures"><span class="toc-number">6.4.</span> <span class="toc-text">pytest.mark.usefixtures</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-3"><span class="toc-number">6.4.1.</span> <span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-3"><span class="toc-number">6.4.2.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E8%AE%B0"><span class="toc-number">6.5.</span> <span class="toc-text">自定义标记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B3%A8%E5%86%8C%E6%A0%87%E8%AE%B0"><span class="toc-number">6.5.1.</span> <span class="toc-text">注册标记</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A0%87%E8%AE%B0%E5%87%BD%E6%95%B0"><span class="toc-number">6.5.2.</span> <span class="toc-text">标记函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A0%87%E8%AE%B0%E7%B1%BB"><span class="toc-number">6.5.3.</span> <span class="toc-text">标记类</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%80%9A%E8%BF%87%E6%A0%87%E8%AE%B0%E7%AD%9B%E9%80%89%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0"><span class="toc-number">6.5.4.</span> <span class="toc-text">通过标记筛选测试函数</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%96%AD%E8%A8%80"><span class="toc-number">7.</span> <span class="toc-text">断言</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B8%B8%E8%A7%84%E6%96%AD%E8%A8%80"><span class="toc-number">7.1.</span> <span class="toc-text">常规断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%AD%E8%A8%80"><span class="toc-number">7.2.</span> <span class="toc-text">自定义断言</span></a></li></ol></li></ol>
                </div>
            
            <hr />
            <div itemprop="articleBody"><h2 id="pytest-简介"><a href="#pytest-简介" class="headerlink" title="pytest 简介"></a>pytest 简介</h2><ul>
<li><p>pytest 是一个非常成熟的 python 的单元框架，比 unittest 更灵活。</p>
</li>
<li><p>pytest 可以和 selenium，requests，appium 结合实现 web 自动化，接口自动化，app 自</p>
<p>动化。</p>
</li>
<li><p>pytest 可以实现测试函数的跳过以及重新执行失败的测试函数。</p>
</li>
<li><p>pytest 可以和 allure 生成非常美观的测试报告。</p>
</li>
<li><p>pytest 可以和 Jenkins 持续集成。</p>
</li>
<li><p>pytest 有很多非常强大的插件，并且这些插件能够实现很多的实用的操作。</p>
<ul>
<li>pytest：单元测试。</li>
<li>pytest-xdist：测试函数分布式执行，多CPU分发。</li>
<li>pytest-ordering：用于改变测试函数的执行顺序（从上到下）。</li>
<li>pytest-rerunfailures：测试函数失败后重跑。</li>
<li>pytest-html：生成 html 格式的自动化测试报告。</li>
<li>allure-pytest：用于生成美观的测试报告。</li>
<li>ppyaml：操作 yaml 文件。</li>
</ul>
</li>
</ul>
<h2 id="编写测试函数的默认规则"><a href="#编写测试函数的默认规则" class="headerlink" title="编写测试函数的默认规则"></a>编写测试函数的默认规则</h2><h3 id="编写规则"><a href="#编写规则" class="headerlink" title="编写规则"></a>编写规则</h3><ul>
<li>模块名必须以 test_ 开头。</li>
<li>测试类必须以 Test 开头，并且不能有 init 函数。</li>
<li>测试函数必须以 test 开头。</li>
</ul>
<p><strong>注意：</strong>测试模块导入的包如果满足上述条件并且引用了包中的内容，那么包中的测试函数也会被执行。</p>
<h3 id="函数形式编写用例"><a href="#函数形式编写用例" class="headerlink" title="函数形式编写用例"></a>函数形式编写用例</h3><p>规则：模块名以 test_ 开头，用例方法名以 test 开头。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># \testcases\test_demo1.py</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo</span>():</span><br><span class="line">    <span class="keyword">assert</span> <span class="number">100</span> == <span class="number">100</span></span><br></pre></td></tr></table></figure>

<h3 id="类形式编写用例"><a href="#类形式编写用例" class="headerlink" title="类形式编写用例"></a>类形式编写用例</h3><p>规则：模块名以 test_ 开头，测试类名以 Test 开头，用例方法名以 test 开头。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># test_demo2.py</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestDome</span>:</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_demo1</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">assert</span> <span class="number">11</span> == <span class="number">11</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_demo</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">assert</span> <span class="number">22</span> == <span class="number">21</span></span><br></pre></td></tr></table></figure>

<h2 id="运行-pytest-方式"><a href="#运行-pytest-方式" class="headerlink" title="运行 pytest 方式"></a>运行 pytest 方式</h2><h3 id="命令行模式"><a href="#命令行模式" class="headerlink" title="命令行模式"></a>命令行模式</h3><h4 id="pytest-命令的使用"><a href="#pytest-命令的使用" class="headerlink" title="pytest 命令的使用"></a>pytest 命令的使用</h4><p>指令：pytest</p>
<p>操作对象：</p>
<ul>
<li>为空表示针对所有符合条件的测试函数。</li>
<li>测试目录。例如：.&#x2F;interface_testcase。</li>
<li>测试文件。例如：.&#x2F;interface_testcase&#x2F;test_login.py。</li>
<li>测试类。例如：<code>测试文件::测试类</code>。</li>
<li>测试函数。例如：<code>测试文件::测试类::测试方法</code>。</li>
</ul>
<p>选项：</p>
<ul>
<li><code>-s</code>：表示输出调试信息，包括 print 打印的信息。</li>
<li><code>-v</code>：显示更详细的信息。</li>
<li><code>-n=数字</code>：使用多线程或者分布式运行测试函数，数字表示使用多少个线程执行（前提是安装了 pytest-xdist 插件）。</li>
<li><code>--reruns=数字</code>：失败后可以重新执行的次数（前提是安装了 pytest-rerunfailures 插件）。</li>
<li><code>-x</code>：出现一个测试函数执行失败就停止测试。</li>
<li><code>-maxfail=数字</code>：出现几个测试函数执行失败才停止测试。</li>
<li><code>--html 报告路径</code>：生成 html 的测试报告（前提是安装了 pytest-html 插件）。</li>
<li><code>-k 字符串</code>：只运行测试函数名称中包含指定字符串的测试函数。支持 <code>and/or/not</code> 逻辑表达式。</li>
<li><code>-m=&#39;字符串&#39;</code>：执行指定标记的测试函数。支持 <code>and/or/not</code> 逻辑表达式。</li>
<li><code>--co</code>：全称是 –collect-only，表示只收集用例，不执行。</li>
<li><code>--timeout=数字</code>：用例执行的最大时长，如果超时没有执行完，就是强制停止用例。单位是秒（前提是安装了 pytest-timeout 插件）。</li>
</ul>
<h4 id="自定义命令行参数"><a href="#自定义命令行参数" class="headerlink" title="自定义命令行参数"></a>自定义命令行参数</h4><p>以上参数都是 Pytest 自带的或者三方插件给我们提供的参数，当这些参数不能满足我们的需求的时候，可以使用钩子函数 <strong>pytest_addoption</strong> 自定义一些命令行参数。例如：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">pytest_addoption</span>(<span class="params">parser</span>):</span><br><span class="line">    parser.addoption()</span><br></pre></td></tr></table></figure>

<blockquote>
<p>parser.addoption() 传入参数说明：</p>
<p><strong>name：</strong>自定义命令行参数的名字，可以是：”foo”， “-foo” 或 “–foo”；</p>
<p><strong>action：</strong>在命令行中遇到此参数时要采取的基本操作类型；</p>
<p>nargs：应该使用的命令行参数的数量；</p>
<p>const：某些操作和nargs选择所需的常量值； <strong>default：</strong>如果参数不在命令行中，则生成的默认值。</p>
<p>type：命令行参数应该转换为的类型；</p>
<p>choices：参数允许值的容器；</p>
<p>required：命令行选项是否可以省略（仅可选）；</p>
<p><strong>help：</strong>对参数作用的简要说明；</p>
<p>metavar：用法消息中参数的名称；</p>
<p>dest：要添加到 parse_args() 返回的对象中的属性的名称；</p>
</blockquote>
<p>例如添加 –logLevel 参数：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">pytest_addoption</span>(<span class="params">parser</span>):</span><br><span class="line">    parser.addoption(</span><br><span class="line">        <span class="string">&quot;--logLevel&quot;</span>,</span><br><span class="line">        action=<span class="string">&quot;store&quot;</span>,</span><br><span class="line">        default=<span class="string">&quot;DEBUG&quot;</span>,</span><br><span class="line">        <span class="built_in">help</span>=<span class="string">&quot;DEBUG, INFO，WARNING，ERROR, CRITICAL, 终端日志输出级别&quot;</span>,</span><br><span class="line">    )</span><br></pre></td></tr></table></figure>

<p>参数传进来后的获取途径：</p>
<p>（1）fixture 函数可以通过 request 对象获取：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@pytest.fixture(<span class="params">scope=<span class="string">&quot;function&quot;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">do_something</span>(<span class="params">request</span>):</span><br><span class="line">    logLevel = request.config.getoption(<span class="string">&quot;--logLevel&quot;</span>)</span><br></pre></td></tr></table></figure>

<p>（2）hook 函数可以通过 seesion 对象获取：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">pytest_sessionstart</span>(<span class="params">session</span>):</span><br><span class="line">    logLevel = session.config.option.logLevel</span><br></pre></td></tr></table></figure>

<p>（3）hook 函数可以通过 item 对象获取：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">pytest_runtest_teardown</span>(<span class="params">item</span>):</span><br><span class="line">    logLevel = item.session.config.option.logLevel</span><br></pre></td></tr></table></figure>

<p>（4）测试函数可以通过 pytestconfig 对象获取：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">test_xxx</span>(<span class="params">pytestconfig</span>):</span><br><span class="line">    log_level = pytestconfig.option.logLevel</span><br><span class="line">    log_level = pytestconfig.getoption(<span class="string">&quot;logLevel&quot;</span>)</span><br></pre></td></tr></table></figure>

<h3 id="主函数模式"><a href="#主函数模式" class="headerlink" title="主函数模式"></a>主函数模式</h3><p>在 main 函数使用 pytest.main() 执行测试函数。pytest.main() 可以传入一个数组作为参数，传入的数组可以携带命令模式中的选项或操作对象数据。例如：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pytest.main([<span class="string">&#x27;-vs&#x27;</span>,<span class="string">&#x27;./interface_testcase/test_interface.py&#x27;</span>])</span><br></pre></td></tr></table></figure>

<h2 id="pytest-ini-全局配置文件"><a href="#pytest-ini-全局配置文件" class="headerlink" title="pytest.ini 全局配置文件"></a>pytest.ini 全局配置文件</h2><p>pytest.ini 文件是 pytest 框架的核心配置文件：</p>
<ul>
<li>存放位置：一般放在项目的根目录。</li>
<li>编码：必须是 ANSI 或 GB2312。</li>
<li>作用：修改 pytest 默认的行为。</li>
<li>运行规则：不管是命令行模式运行，还是主函数的模式运行，都会去读取这个配置文件。</li>
</ul>
<h3 id="pytest-ini-文件内容"><a href="#pytest-ini-文件内容" class="headerlink" title="pytest.ini 文件内容"></a>pytest.ini 文件内容</h3><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[pytest]</span></span><br><span class="line"><span class="comment"># 命令行默认参数，用空格分隔</span></span><br><span class="line"><span class="attr">addopts</span> = -vs </span><br><span class="line"><span class="comment"># 目录</span></span><br><span class="line"><span class="attr">testpaths</span> = ./testcase </span><br><span class="line"><span class="comment">#模块名的规则</span></span><br><span class="line"><span class="attr">python_files</span> = test_*.py </span><br><span class="line"><span class="comment">#类名的规则</span></span><br><span class="line"><span class="attr">python_classes</span> = Test* </span><br><span class="line"><span class="comment">#函数名的规则</span></span><br><span class="line"><span class="attr">python_functions</span> = test_* </span><br><span class="line"><span class="attr">markers</span> =</span><br><span class="line">	smoke:冒烟函数</span><br><span class="line">	user_manage:用户管理模块</span><br><span class="line">	product_manage:商品管理模块</span><br></pre></td></tr></table></figure>

<p><strong>markers 的用法：</strong></p>
<ol>
<li>在测试函数上添加注解 <code>@pytest.mark.smoke</code> ，一个测试函数可以添加多个。</li>
<li>执行 pytest 时添加选项 <code>-m=标记名称</code>，表示只执行被标记的测试函数。如果要执行不同类型标记的函数，可以添加 <code>-m=标记名称1 or 标记名称 2</code>。</li>
<li>markers 的作用：将不同的测试函数进行分组。</li>
</ol>
<h2 id="使用-fixture-实现部分前后置操作"><a href="#使用-fixture-实现部分前后置操作" class="headerlink" title="使用 fixture 实现部分前后置操作"></a>使用 fixture 实现部分前后置操作</h2><h3 id="pytest-fixture-参数"><a href="#pytest-fixture-参数" class="headerlink" title="@pytest.fixture() 参数"></a>@pytest.fixture() 参数</h3><p>@pytest.fixture() 共有五个参数：</p>
<ul>
<li>scope：被标记的 fixture 函数的作用域。</li>
<li>autouse：该 fixture 函数是否自动实现前后置，默认为 False。</li>
<li>params：实现参数化。</li>
<li>ids：对参数起别名，必须和 params 一起使用。</li>
<li>name：给 fixture 函数起别名。</li>
</ul>
<h4 id="scope-参数"><a href="#scope-参数" class="headerlink" title="scope 参数"></a>scope 参数</h4><p>scope 取值：</p>
<ul>
<li><p>function（默认）：在函数的前后执行。</p>
</li>
<li><p>class：在类的前后执行。</p>
</li>
<li><p>module：在模块的前后执行。</p>
</li>
<li><p>package、session：在整个项目会话的前后执行。需要结合 conftest.py 文件实现。</p>
</li>
</ul>
<h4 id="autouse-参数"><a href="#autouse-参数" class="headerlink" title="autouse 参数"></a>autouse 参数</h4><p>为 True 时自动实现前后置，为 False 时需要手动实现前后置。</p>
<p>当 scope 不同取值时手动实现前后置地方式：</p>
<ul>
<li>scope&#x3D;function ：在函数参数添加 fixture 函数的名称，如果 fixture 函数有通过 return 或 yield 返回值的话，那么可以把返回值传递到测试函数中。</li>
<li>scope&#x3D;class：在类名上添加装饰器 **@pytest.mark.usefixtures(“fixture 函数名称”)**。</li>
</ul>
<h4 id="params-参数"><a href="#params-参数" class="headerlink" title="params 参数"></a>params 参数</h4><p><code>fixture</code> 函数可以被参数化，在这种情况下，它们将被多次调用，每次执行一组依赖于该 <code>fixture</code> 的测试。</p>
<p>通过给 <code>@pytest</code> 的 <code>params</code> 参数赋值一个列表。 <code>Fixture</code> 函数将执行列表中的每个值，并可以通过 <code>request.param</code> 访问一个值。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pytest</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@pytest.fixture(<span class="params">scope=<span class="string">&#x27;function&#x27;</span>, autouse=<span class="literal">False</span>, params=[<span class="string">&#x27;smtp.gmail.com&#x27;</span>, <span class="string">&#x27;mail.python.org&#x27;</span>]</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fixture_method</span>(<span class="params">request</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\n前置&#x27;</span>)</span><br><span class="line">    <span class="keyword">yield</span> request.param</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\n后置&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestModule01</span>:</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_001</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_002</span>(<span class="params">self, fixture_method</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;参数：<span class="subst">&#123;fixture_method&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_003</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<p>结果：</p>
<p><img src="/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/image-20240223111830636.png"></p>
<p>注：如果有多个前后置函数携带 params 参数，那么会将这些前后置函数的 params 参数进行笛卡尔积后依次执行测试函数。</p>
<h4 id="ids-参数"><a href="#ids-参数" class="headerlink" title="ids 参数"></a>ids 参数</h4><p>作用：给参数起别名，必须和 params 一起使用。</p>
<h4 id="name-参数"><a href="#name-参数" class="headerlink" title="name 参数"></a>name 参数</h4><p>作用：给 fixture 函数起别名，原来的 fixture 函数的名称会失效。</p>
<h3 id="conftest-py-文件"><a href="#conftest-py-文件" class="headerlink" title="conftest.py 文件"></a><strong>conftest.py 文件</strong></h3><p>作用：用于存放通用的 fixture 函数。文件名称固定，不能改变。</p>
<p>存放位置：从项目根目录开始，每个层级都可以有个conftest.py 文件。</p>
<p>注：在 conftest.py 文件里面所有的 fixture 函数在被调用时都不需要导包。</p>
<h3 id="各种前后固件的优先级"><a href="#各种前后固件的优先级" class="headerlink" title="各种前后固件的优先级"></a>各种前后固件的优先级</h3><p>作用域优先级：会话 &gt; 模块 &gt; 类 &gt; 函数</p>
<p>类型优先级：fixtrue &gt; setup&#x2F;teardown</p>
<p>fixture 作用域相同的情况下，外层 fixture 先执行。</p>
<p>固件优先级从高到低排序：</p>
<ol>
<li>fixture 的 session&#x2F;package 级别</li>
<li>fixture 的 module 级别</li>
<li>setup_module、teardown_module 级别</li>
<li>fixture 的 class 级别</li>
<li>setup_class、teardown_class 级别</li>
<li>fixture 的 function 级别</li>
<li>setup_method、teardown_method 级别</li>
</ol>
<p><strong>注1：</strong><code>setup_method</code> 和 <code>setup_function</code> 的区别。<code>setup_function</code> 是在基于函数式的用例写法使用的，<code>setup_method</code> 是基于类式的用例写法使用的。</p>
<p><strong>注2：</strong>如果 fixture 出现相同的函数名，只会执行内层的 fixture 函数。在实际项目中，不想用某些外层的 fixture，可以在内层定义一个同名的 fixture，里面写 pass，相当于抵消掉了外层 fixture 的作用。</p>
<h2 id="pytest-mark-标记的使用"><a href="#pytest-mark-标记的使用" class="headerlink" title="pytest.mark 标记的使用"></a>pytest.mark 标记的使用</h2><h3 id="pytest-mark-parametrize"><a href="#pytest-mark-parametrize" class="headerlink" title="pytest.mark.parametrize"></a>pytest.mark.parametrize</h3><blockquote>
<h4 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h4><p>将用例数据和用例执行的逻辑代码分离，并实现根据用例，自动生成测试用例。</p>
<h4 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h4><p>argnames：参数名称，用于将参数值传递给函数。</p>
<p>argvalues：参数值，参数类型为列表或元组。</p>
<h4 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pytest</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestUserFun01</span>:</span><br><span class="line"></span><br><span class="line"><span class="meta">    @pytest.mark.parametrize(<span class="params"><span class="string">&#x27;user_name&#x27;</span>, [<span class="string">&#x27;lin&#x27;</span>, <span class="string">&#x27;cheng&#x27;</span>, <span class="string">&#x27;yang&#x27;</span>]</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_user_001</span>(<span class="params">self, user_name</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;\n用户名称：<span class="subst">&#123;user_name&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_user_002</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_user_003</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<p><strong>执行结果：</strong></p>
<p><img src="/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/image-20240223183853984.png"></p>
</blockquote>
<h3 id="pytest-mark-skip"><a href="#pytest-mark-skip" class="headerlink" title="pytest.mark.skip"></a>pytest.mark.skip</h3><blockquote>
<h4 id="作用-1"><a href="#作用-1" class="headerlink" title="作用"></a>作用</h4><p>无条件跳过测试用例。</p>
<h4 id="参数-1"><a href="#参数-1" class="headerlink" title="参数"></a>参数</h4><p>reason：跳过测试测试函数的原因。</p>
<h4 id="示例-1"><a href="#示例-1" class="headerlink" title="示例"></a>示例</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo01</span>():</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 不写跳过原因</span></span><br><span class="line"><span class="meta">@pytest.mark.skip</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo02</span>():</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 写跳过原因</span></span><br><span class="line"><span class="meta">@pytest.mark.skip(<span class="params">reason=<span class="string">&#x27;不需要执行&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo03</span>():</span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<p><strong>执行结果：</strong></p>
<p><img src="/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/image-20240226114115158.png"></p>
</blockquote>
<h3 id="pytest-mark-skipif"><a href="#pytest-mark-skipif" class="headerlink" title="pytest.mark.skipif"></a>pytest.mark.skipif</h3><blockquote>
<h4 id="作用-2"><a href="#作用-2" class="headerlink" title="作用"></a>作用</h4><p>根据条件来决定是否跳过用例的执行， 如果条件为 <code>True</code> 则跳过测试函数执行。</p>
<h4 id="参数-2"><a href="#参数-2" class="headerlink" title="参数"></a>参数</h4><p>condition：跳过的条件</p>
<p>reason：跳过的原因</p>
<h4 id="示例-2"><a href="#示例-2" class="headerlink" title="示例"></a>示例</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a = <span class="number">30</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@pytest.mark.skipif(<span class="params">a &gt; <span class="number">20</span>, reason=<span class="string">&#x27;条件不成立，不执行&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo</span>():</span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<p><strong>执行结果：</strong></p>
<p><img src="/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/image-20240226114400462.png"></p>
</blockquote>
<h3 id="pytest-mark-usefixtures"><a href="#pytest-mark-usefixtures" class="headerlink" title="pytest.mark.usefixtures"></a>pytest.mark.usefixtures</h3><blockquote>
<h4 id="作用-3"><a href="#作用-3" class="headerlink" title="作用"></a>作用</h4><p>手动给测试类添加类级别的 fixture 函数。</p>
<h4 id="示例-3"><a href="#示例-3" class="headerlink" title="示例"></a>示例</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@pytest.fixture(<span class="params">scope=<span class="string">&#x27;class&#x27;</span>, autouse=<span class="literal">False</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fixture_demo_01</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\nfixture_demo_01 before&#x27;</span>)</span><br><span class="line">    <span class="keyword">yield</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\nfixture_demo_01 after&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@pytest.fixture(<span class="params">scope=<span class="string">&#x27;class&#x27;</span>, autouse=<span class="literal">False</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fixture_demo_02</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\nfixture_demo_02 before&#x27;</span>)</span><br><span class="line">    <span class="keyword">yield</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;\nfixture_demo_02 after&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@pytest.mark.usefixtures(<span class="params"><span class="string">&#x27;fixture_demo_01&#x27;</span>, <span class="string">&#x27;fixture_demo_02&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestDome</span>:</span><br><span class="line">    <span class="comment"># 函数用例 指定测试夹具</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_02</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;----测试用例：test_01------&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 函数用例 指定测试夹具</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_03</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;----测试用例：test_02------&#x27;</span>)</span><br></pre></td></tr></table></figure>

<p><strong>执行结果：</strong></p>
<p><img src="/blog/2024/02/26/Python%20Module/Pytest/Pytest%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD/image-20240226115134739.png"></p>
</blockquote>
<h3 id="自定义标记"><a href="#自定义标记" class="headerlink" title="自定义标记"></a>自定义标记</h3><h4 id="注册标记"><a href="#注册标记" class="headerlink" title="注册标记"></a>注册标记</h4><p>pytest.ini 文件注册标记的语法如下：</p>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[pytest]</span></span><br><span class="line"></span><br><span class="line"><span class="attr">markers</span> =</span><br><span class="line">    标记1</span><br><span class="line">    标记2</span><br></pre></td></tr></table></figure>

<h4 id="标记函数"><a href="#标记函数" class="headerlink" title="标记函数"></a>标记函数</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 用例前面加载标签：@pytest.mark.标签名 </span></span><br><span class="line"><span class="meta">@pytest.mark.smoke</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_demo</span>():</span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<h4 id="标记类"><a href="#标记类" class="headerlink" title="标记类"></a>标记类</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 方式一：直接类上面打标记</span></span><br><span class="line"><span class="meta">@pytest.mark.smoke</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestClass01</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_demo1</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式二：通过类属性pytestmark,可以同时添加多个标记</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TestClass02</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    pytestmark = [pytest.mark.smoke, pytest.mark.user_manage]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">test_demo1</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br></pre></td></tr></table></figure>

<h4 id="通过标记筛选测试函数"><a href="#通过标记筛选测试函数" class="headerlink" title="通过标记筛选测试函数"></a>通过标记筛选测试函数</h4><p>语法：<code>pytest -m=&#39;标签名&#39;</code>，支持 <code>and/or/not</code> 逻辑表达式。</p>
<h2 id="断言"><a href="#断言" class="headerlink" title="断言"></a>断言</h2><h3 id="常规断言"><a href="#常规断言" class="headerlink" title="常规断言"></a>常规断言</h3><p>Pytest 直接使用 Python 自带的 assert 语句进行断言。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">test_case_001</span>():</span><br><span class="line">    <span class="keyword">assert</span> <span class="number">1</span> == <span class="number">1</span></span><br></pre></td></tr></table></figure>

<h3 id="自定义断言"><a href="#自定义断言" class="headerlink" title="自定义断言"></a>自定义断言</h3><p>断言失败实际上都是捕获 <code>AssertionError（断言异常）</code> 异常，因此只需要定义一个函数，抛出 <code>AssertionError</code> 异常就可以了。当表达式可能是一些比较复杂的封装时，可以使用自定义断言。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">AssertCommon</span>:</span><br><span class="line">    </span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">assert_true</span>(<span class="params">expect</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;断言为真&quot;&quot;&quot;</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> expect:</span><br><span class="line">            <span class="keyword">raise</span> AssertionError(<span class="string">f&quot;&lt;<span class="subst">&#123;expect&#125;</span>&gt;不为真&quot;</span>)</span><br></pre></td></tr></table></figure>

</div>
        </div>
        
        <footer class="kratos-entry-footer clearfix">
            
            <div class="footer-tag clearfix">
                <div class="pull-left">
                <i class="fa fa-tags"></i>
                    <a class="tag-none-link" href="/blog/tags/Pytest/" rel="tag">Pytest</a>, <a class="tag-none-link" href="/blog/tags/Python/" rel="tag">Python</a>
                </div>
                <div class="pull-date">
                    <time datetime="2025-11-20T11:35:22.287Z" itemprop="dateModified">最后编辑：2025-11-20</time>
                </div>
            </div>
        </footer>
    </div>
    
        <nav class="navigation post-navigation clearfix" role="navigation">
            
            <div class="nav-previous clearfix">
                <a title=" 【Docker】应用部署" href="/blog/2024/02/26/Docker/应用部署/">&lt; 上一篇</a>
            </div>
            
            
            <div class="nav-next clearfix">
                <a title=" 【Request】基本使用" href="/blog/2024/02/27/Python Module/Request/Request基本使用/">下一篇 &gt;</a>
            </div>
            
        </nav>
    
    
</article>

        

            </section>

        

                
            

<section id="kratos-widget-area" class="col-md-4 hidden-xs hidden-sm">
    <!-- 文章和页面根据splitter来分割，没有的话就从头开始设置为sticky -->
    
    
                <aside id="krw-about" class="widget widget-kratos-about clearfix">
    <div class="photo-background"></div>
    <div class="photo-wrapper clearfix">
        <div class="photo-wrapper-tip text-center">
            <img class="about-photo" src="/blog/images/avatar.webp" loading="lazy" decoding="auto" />
        </div>
    </div>
    <div class="textwidget">
        <p class="text-center">极简主义</p>
    </div>
    <div class="site-meta">
        <a class="meta-item" href="/blog/archives/">
            <span class="title">
                文章
            </span>
            <span class="count">
                72
            </span>
        </a>
        <a class="meta-item" href="/blog/categories/">
            <span class="title">
                分类
            </span>
            <span class="count">
                9
            </span>
        </a>
        <a class="meta-item" href="/blog/tags/">
            <span class="title">
                标签
            </span>
            <span class="count">
                27
            </span>
        </a>
    </div>
</aside>
            
                    <div class="sticky-area">
                
                    <aside id="krw-toc" class="widget widget-kratos-toc clearfix toc-div-class" >
    <div class="photo-background"></div>
    <h4 class="widget-title no-after">
        <i class="fa fa-compass"></i>
        文章目录
        <span class="toc-progress-bar" role="progressbar" aria-label="阅读进度："></span>
    </h4>
    <div class="textwidget">
        <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-%E7%AE%80%E4%BB%8B"><span class="toc-text">pytest 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%96%E5%86%99%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%E7%9A%84%E9%BB%98%E8%AE%A4%E8%A7%84%E5%88%99"><span class="toc-text">编写测试函数的默认规则</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BC%96%E5%86%99%E8%A7%84%E5%88%99"><span class="toc-text">编写规则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BD%A2%E5%BC%8F%E7%BC%96%E5%86%99%E7%94%A8%E4%BE%8B"><span class="toc-text">函数形式编写用例</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E5%BD%A2%E5%BC%8F%E7%BC%96%E5%86%99%E7%94%A8%E4%BE%8B"><span class="toc-text">类形式编写用例</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E8%A1%8C-pytest-%E6%96%B9%E5%BC%8F"><span class="toc-text">运行 pytest 方式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%A8%A1%E5%BC%8F"><span class="toc-text">命令行模式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#pytest-%E5%91%BD%E4%BB%A4%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">pytest 命令的使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0"><span class="toc-text">自定义命令行参数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E5%87%BD%E6%95%B0%E6%A8%A1%E5%BC%8F"><span class="toc-text">主函数模式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-ini-%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-text">pytest.ini 全局配置文件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-ini-%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9"><span class="toc-text">pytest.ini 文件内容</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-fixture-%E5%AE%9E%E7%8E%B0%E9%83%A8%E5%88%86%E5%89%8D%E5%90%8E%E7%BD%AE%E6%93%8D%E4%BD%9C"><span class="toc-text">使用 fixture 实现部分前后置操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-fixture-%E5%8F%82%E6%95%B0"><span class="toc-text">@pytest.fixture() 参数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#scope-%E5%8F%82%E6%95%B0"><span class="toc-text">scope 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#autouse-%E5%8F%82%E6%95%B0"><span class="toc-text">autouse 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#params-%E5%8F%82%E6%95%B0"><span class="toc-text">params 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ids-%E5%8F%82%E6%95%B0"><span class="toc-text">ids 参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#name-%E5%8F%82%E6%95%B0"><span class="toc-text">name 参数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#conftest-py-%E6%96%87%E4%BB%B6"><span class="toc-text">conftest.py 文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%90%84%E7%A7%8D%E5%89%8D%E5%90%8E%E5%9B%BA%E4%BB%B6%E7%9A%84%E4%BC%98%E5%85%88%E7%BA%A7"><span class="toc-text">各种前后固件的优先级</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#pytest-mark-%E6%A0%87%E8%AE%B0%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">pytest.mark 标记的使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-parametrize"><span class="toc-text">pytest.mark.parametrize</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8"><span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0"><span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B"><span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-skip"><span class="toc-text">pytest.mark.skip</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-1"><span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0-1"><span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-1"><span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-skipif"><span class="toc-text">pytest.mark.skipif</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-2"><span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%82%E6%95%B0-2"><span class="toc-text">参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-2"><span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#pytest-mark-usefixtures"><span class="toc-text">pytest.mark.usefixtures</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8-3"><span class="toc-text">作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-3"><span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E8%AE%B0"><span class="toc-text">自定义标记</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B3%A8%E5%86%8C%E6%A0%87%E8%AE%B0"><span class="toc-text">注册标记</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A0%87%E8%AE%B0%E5%87%BD%E6%95%B0"><span class="toc-text">标记函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A0%87%E8%AE%B0%E7%B1%BB"><span class="toc-text">标记类</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%80%9A%E8%BF%87%E6%A0%87%E8%AE%B0%E7%AD%9B%E9%80%89%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0"><span class="toc-text">通过标记筛选测试函数</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%96%AD%E8%A8%80"><span class="toc-text">断言</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B8%B8%E8%A7%84%E6%96%AD%E8%A8%80"><span class="toc-text">常规断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%AD%E8%A8%80"><span class="toc-text">自定义断言</span></a></li></ol></li></ol>
    </div>
</aside>
                
                
  <aside id="krw-categories" class="widget widget-kratos-categories clearfix">
    <h4 class="widget-title"><i class="fa fa-folder"></i>分类目录</h4>
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Docker/">Docker</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Idea/">Idea</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Java/">Java</a><span class="category-list-count">11</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Linux/">Linux</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/MySQL/">MySQL</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Python/">Python</a><span class="category-list-count">11</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Selenium/">Selenium</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/SpringBoot/">SpringBoot</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/SpringCloud/">SpringCloud</a><span class="category-list-count">13</span></li></ul>
  </aside>


            
                
  <aside id="krw-tags" class="widget widget-kratos-tags clearfix">
    <h4 class="widget-title"><i class="fa fa-tags"></i>标签聚合</h4>
      <div class="tag-clouds">
        <a href="/blog/tags/CORS/" style="font-size: 0.8em;">CORS</a> <a href="/blog/tags/Docker/" style="font-size: 0.8em;">Docker</a> <a href="/blog/tags/Dubbo/" style="font-size: 0.8em;">Dubbo</a> <a href="/blog/tags/ELK/" style="font-size: 0.8em;">ELK</a> <a href="/blog/tags/Elasticsearch/" style="font-size: 0.8em;">Elasticsearch</a> <a href="/blog/tags/Eureka/" style="font-size: 0.8em;">Eureka</a> <a href="/blog/tags/Feign/" style="font-size: 0.8em;">Feign</a> <a href="/blog/tags/Gateway/" style="font-size: 0.8em;">Gateway</a> <a href="/blog/tags/Idea/" style="font-size: 0.8em;">Idea</a> <a href="/blog/tags/Java/" style="font-size: 0.8em;">Java</a> <a href="/blog/tags/JavaWeb/" style="font-size: 0.8em;">JavaWeb</a> <a href="/blog/tags/Linux/" style="font-size: 0.8em;">Linux</a> <a href="/blog/tags/Maven/" style="font-size: 0.8em;">Maven</a> <a href="/blog/tags/MySQL/" style="font-size: 0.8em;">MySQL</a> <a href="/blog/tags/Mybatis/" style="font-size: 0.8em;">Mybatis</a> <a href="/blog/tags/Nacos/" style="font-size: 0.8em;">Nacos</a> <a href="/blog/tags/Pytest/" style="font-size: 0.8em;">Pytest</a> <a href="/blog/tags/Python/" style="font-size: 0.8em;">Python</a>
      </div>
  </aside>

            
                
  <aside id="krw-posts" class="widget widget-kratos-posts">
  <h4 class="widget-title"><i class="fa fa-file"></i>最新文章</h4>
  <div class="tab-content">
      <ul class="list-group">
        
        
          
          
            <a class="list-group-item" href="/blog/2024/04/07/Java%E6%97%A5%E5%BF%97%E6%A1%86%E6%9E%B6/Java%E6%97%A5%E5%BF%97%E6%A1%86%E6%9E%B6/"><i class="fa  fa-book"></i> 【Java】常见的日志框架</a>
            
          
        
          
          
            <a class="list-group-item" href="/blog/2024/04/06/SpringCloud/ElasticStack/Elasticsearch%E6%90%9C%E7%B4%A2%E8%AF%AD%E6%B3%95/"><i class="fa  fa-book"></i> 【ES】搜索语法</a>
            
          
        
          
          
            <a class="list-group-item" href="/blog/2024/04/03/SpringCloud/ElasticStack/Elasticsearch%E7%B4%A2%E5%BC%95%E9%85%8D%E7%BD%AE/"><i class="fa  fa-book"></i> 【ES】索引配置</a>
            
          
        
          
          
            <a class="list-group-item" href="/blog/2024/04/02/SpringCloud/ElasticStack/Kibana%E5%B8%B8%E7%94%A8%E5%8A%9F%E8%83%BD/"><i class="fa  fa-book"></i> 【Kibana】常用功能</a>
            
          
        
          
          
            <a class="list-group-item" href="/blog/2024/04/02/SpringCloud/ElasticStack/IK%E5%88%86%E8%AF%8D%E5%99%A8/"><i class="fa  fa-book"></i> 【IK 分词器】基本使用</a>
            
          
        
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
          
            
      </ul>
  </div>
  </aside>

            
    </div>
</section>
        
        </div>
    </div>
</div>
<footer>
    <div id="footer"  >
        <div class="container">
            <div class="row">
                <div class="col-md-6 col-md-offset-3 footer-list text-center">
                    <ul class="kratos-social-icons">
                        <!-- Keep for compatibility -->
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        <!-- New links -->
                        
                    </ul>
                    <ul class="kratos-copyright">
                        <div>
                            <li>&copy; 2025 溪岚花的博客 版权所有.</li>
                            <li>本站已运行<span id="span_dt">Loading...</span></li>
                        </div>
                        <div>
                            <li>Theme <a href="https://github.com/Candinya/Kratos-Rebirth" target="_blank">Kratos:Rebirth</a></li>
                            <li>Site built with&nbsp;<i class="fa fa-heart throb" style="color:#d43f57"></i>&nbsp;by 林家隆.</li>
                        </div>
                        <div>
                            <li>Powered by <a href="https://hexo.io" target="_blank" rel="nofollow">Hexo</a></li>
                            <li>Hosted on <a href="https://gitee.com/" target="_blank">Gitee Pages</a></li>
                        </div>
                        <div>
                            
                            
                        </div>
                    </ul>
                </div>
            </div>
        </div>
        <div class="kr-tool text-center">
            <div class="tool">
                
                    <div class="box search-box">
                        <a href="/blog/search/">
                            <span class="fa fa-search"></span>
                        </a>
                    </div>
                
                
                    <div class="box theme-box" id="darkmode-switch">
                        <span class="fa fa-adjust"></span>
                    </div>
                
                
                
            </div>
            <div class="box gotop-box">
                <span class="fa fa-chevron-up"></span>
            </div>
        </div>
    </div>
</footer>
</div>
</div>

        <script defer src="/blog/vendors/bootstrap@3.3.4/dist/js/bootstrap.min.js"></script>
<script defer src="/blog/vendors/nprogress@0.2.0/nprogress.js"></script>
<script>
    if (!window.kr) {
        window.kr = {};
    }
    window.kr.notMobile = (!(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)));
    window.kr.siteRoot = "/blog/";
</script>





    <script defer src="/blog/vendors/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

<script defer src="/blog/js/kratosr.min.js"></script>
<script defer src="/blog/js/pjax.min.js"></script>



<!-- Extra support for third-party plguins  -->


    </body>
</html>